package com.gzsxy.esjy.service.netty.handler;


import cn.hutool.core.util.URLUtil;
import com.gzsxy.esjy.common.Assert;
import com.gzsxy.esjy.handler.BaseHandler;
import com.gzsxy.esjy.request.impl.FileHttpServletRequest;

import com.gzsxy.esjy.response.NettyHttpResponse;
import com.gzsxy.esjy.service.netty.client.NettyHttpClient;
import com.gzsxy.esjy.service.netty.client.ProxyTarget;
import com.gzsxy.esjy.service.netty.decoder.FilePathParser;
import com.gzsxy.esjy.service.netty.fileServer.configure.ServerStaticProperties;
import com.gzsxy.esjy.service.netty.service.FileDownLoadService;
import com.gzsxy.esjy.service.netty.util.FileUtils;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpResponseStatus;

/**
 * 文件处理器（只有当请求是访问某资源，图片浏览等等才会进入该处理器）
 * @author zhangxiaolong
 * @date 2022/7/11 9:36
 */
public class FileDownloadHandler extends BaseHandler<FileHttpServletRequest> {

	private final FileDownLoadService fileOperateService ;

	private final static String format = "%s/%s/%s/%s";

	private Object content ;

	public FileDownloadHandler(FileDownLoadService pool) {
		super();
		this.fileOperateService = pool;
	}

	@Override
	public void channelRead0(ChannelHandlerContext ctx, FileHttpServletRequest request) throws Exception {
		try {
			//解析参数
			FilePathParser filePath = parseParam(request);
			Assert.isNotNull(filePath, HttpResponseStatus.FORBIDDEN.toString(), HttpResponseStatus.FORBIDDEN.code());

			//暂时关闭代理
			if(ServerStaticProperties.PROXY_ENABLED) {
				ProxyTarget resourcesSystem = ServerStaticProperties.PROXY_TARGET.get(filePath.getSystemId());
				if(resourcesSystem != null) {
					NettyHttpClient.proxyGET(resourcesSystem.getIp(), resourcesSystem.getPort(), ctx.channel(),request);
					return ;
				}
			}
			//文件直接删除
			if(request.isDelete()) {
				FileUtils.deleteFile(ServerStaticProperties.RESOURCES_ROOT+"/"+filePath.getDirectIndex()) ;
				ctx.writeAndFlush(NettyHttpResponse.create(HttpResponseStatus.OK, "文件删除成功", request.getCharset().name())) ;
				return ;
			}
			fileOperateService.downloadFile(filePath,ctx,ServerStaticProperties.RESOURCES_ROOT,request) ;
		}catch(Throwable e) {
			ChannelFuture writeAndFlush = ctx.writeAndFlush(NettyHttpResponse.doExceptionResponse(e, request.getCharset().name()));
			if(!request.isKeepAlive()) {
				writeAndFlush.addListener(ChannelFutureListener.CLOSE);
			}
		}
	}

	/**
	 * 解析参数
	 * @param request
	 * @return
	 */
	public FilePathParser parseParam(FileHttpServletRequest request) {
		try {
			String uri = request.getUri();
			//去除请求参数
			String[] split = uri.split("[?]");
			if(split.length > 1){
				uri = split[0] ;
			}

			if (uri.startsWith(ServerStaticProperties.ABSOLUTE_RESOURCES_PREFIX)) {
				//绝对路径
				return  getFilePath(URLUtil.decode(uri, request.getCharset()));
			} else {
				//相当路径
				return  getFilePathByHash(uri);
			}
		}catch (Exception e) {
			Assert.isNotNull(null,e.getMessage(), HttpResponseStatus.BAD_REQUEST.code(), e);
		}
		return null ;
	}

	/**
	 * 获取文件的真实路径
	 * @param uri
	 * @return
	 */
	private FilePathParser getFilePathByHash(String uri){
		//去除前缀
		uri = uri.replaceFirst(ServerStaticProperties.RESOURCES_PREFIX, "") ;
		//435c4f605b1847898380290507189009/2010/12/08/cec412b5cbe8498ebc5290fb155e714b/60/80.jpg
		FilePathParser filePath = new FilePathParser() ;

		int index = uri.lastIndexOf("/") ;
		Assert.notTrue(index > 0,"url 非法 ",HttpResponseStatus.BAD_REQUEST.code());
		filePath.setSystemId(uri.substring(0, index));
		uri = uri.substring(index+1);
		filePath.setOriDirectIndex(FileUtils.getFilePath("", uri));
		filePath.createDirectIndex();
		return filePath ;
	}

	private FilePathParser getFilePath(String uri){
		//去除前缀
		uri = uri.replaceFirst(ServerStaticProperties.ABSOLUTE_RESOURCES_PREFIX, "");
		FilePathParser filePath = new FilePathParser();

		int index = uri.indexOf("/", 1);
		filePath.setSystemId(uri.substring(1, index));
		uri = uri.substring(index + 1);
		int lastIndex = uri.lastIndexOf("/");
		String baseDir = "";
		String fileName = null;
		if (lastIndex > 0) {
			baseDir = uri.substring(0, lastIndex + 1);
			fileName = uri.substring(lastIndex + 1);
		} else {
			fileName = uri;
		}
		filePath.setOriDirectIndex(getFilePath(baseDir, fileName));
		filePath.createDirectIndex();
		return filePath;
	}

	private String getFilePath(String baseDir, String fileName) {
		if (baseDir == null) {
			baseDir = "";
		} else {
			if (!baseDir.endsWith("/")) {
				baseDir += "/";
			}
			if (baseDir.startsWith("/")) {
				baseDir = baseDir.substring(1);
			}
		}

		return baseDir + fileName;
	}

	@Override
	public Object getContent() {
		return content;
	}
	@Override
	public void setContent(Object content) {
		this.content = content ;
	}


}